#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX_LINE 1024
#define MAX_ARGC 128

char *g_argv[MAX_ARGC];
int g_argc = 0;

const char* get_username()
{
    const char* username = getenv((const char*)"USER");
    return username == NULL ? "None" : username;
}

const char* get_hostname()
{
    const char* hostname = getenv((const char*)"HOSTNAME");
    return hostname == NULL ? "None" : hostname;
}

const char* get_pwd()
{
    const char* pwd = getenv((const char*)"PWD");
    return pwd == NULL ? "None" : pwd;
}

void PrintPrompt()
{
    //1.打印提示符
    printf("[%s@%s %s]# ",get_username(),get_hostname(),get_pwd());
    fflush(stdout);
}

void GetInput(char commandline[])
{
    fgets(commandline,MAX_LINE,stdin);
    commandline[strlen(commandline)-1]='\0';
}

void SpliceString(char commandline[])
{ 
#define space " "
    g_argc = 0;
    g_argv[g_argc++] = strtok(commandline,space);
    while((bool)(g_argv[g_argc++]=strtok(NULL,space)));
    g_argv[g_argc] = NULL;
    --g_argc;
}

bool CheckBuiltIncommand()
{
    if(strcmp(g_argv[0],"cd")==0)
    {
        if(chdir(g_argv[1])==0)
        {
            std::string env = "PATH=";
            env+=g_argv[1];
            putenv(env.c_str());
        }
        //setenv((const char*)"PATH",(const char*)g_argv[1],1);
        return true;
    }
    return false;
}


void Excute()
{
    pid_t pid = fork();
    if(pid==0)
    {
        execvp(g_argv[0],g_argv);
    }
    waitpid(pid,NULL,0);
}


int main()
{
    char commandline[MAX_LINE];
    while(true)
    {
        //1.打印提示符
        PrintPrompt();
        //2.获取输入的字符串
        GetInput(commandline);
        if(strlen(commandline)==0)
            continue;
        //3.以空格为分割，分割字符串,存到命令行参数表中
        SpliceString(commandline);
        //4.检查是否是内建命令，若是由父进程执行
        if(CheckBuiltIncommand())
            continue;
        //5.创建子进程，子进程程序替换执行命令
        Excute();
    }
    return 0;
}
